package com.fll.server.metrics;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;

/**
 * @author fanlei
 * @version 1.0
 * @date 2019年01月25日
 */
public class MetricsCollector {
    private static Map<Integer, MetricsCollector> metricsCollectors = new ConcurrentHashMap();
    private Integer port;
    private AtomicLong readBytes = new AtomicLong();
    private AtomicLong wroteBytes = new AtomicLong();
    private AtomicLong readMsgs = new AtomicLong();
    private AtomicLong wroteMsgs = new AtomicLong();
    private AtomicInteger channels = new AtomicInteger();

    private MetricsCollector() {
    }

    public static MetricsCollector getCollector(Integer port) {
        MetricsCollector collector = (MetricsCollector)metricsCollectors.get(port);
        if (collector == null) {
            Map var2 = metricsCollectors;
            synchronized(metricsCollectors) {
                collector = (MetricsCollector)metricsCollectors.get(port);
                if (collector == null) {
                    collector = new MetricsCollector();
                    collector.setPort(port);
                    metricsCollectors.put(port, collector);
                }
            }
        }

        return collector;
    }

    public static List<Metrics> getAndResetAllMetrics() {
        List<Metrics> allMetrics = new ArrayList();
        Iterator ite = metricsCollectors.entrySet().iterator();

        while(ite.hasNext()) {
            allMetrics.add(((MetricsCollector)((Map.Entry)ite.next()).getValue()).getAndResetMetrics());
        }

        return allMetrics;
    }

    public static List<Metrics> getAllMetrics() {
        List<Metrics> allMetrics = new ArrayList();
        Iterator ite = metricsCollectors.entrySet().iterator();

        while(ite.hasNext()) {
            allMetrics.add(((MetricsCollector)((Map.Entry)ite.next()).getValue()).getMetrics());
        }

        return allMetrics;
    }

    public Metrics getAndResetMetrics() {
        Metrics metrics = new Metrics();
        metrics.setChannels(this.channels.get());
        metrics.setPort(this.port);
        metrics.setReadBytes(this.readBytes.getAndSet(0L));
        metrics.setWroteBytes(this.wroteBytes.getAndSet(0L));
        metrics.setTimestamp(System.currentTimeMillis());
        metrics.setReadMsgs(this.readMsgs.getAndSet(0L));
        metrics.setWroteMsgs(this.wroteMsgs.getAndSet(0L));
        return metrics;
    }

    public Metrics getMetrics() {
        Metrics metrics = new Metrics();
        metrics.setChannels(this.channels.get());
        metrics.setPort(this.port);
        metrics.setReadBytes(this.readBytes.get());
        metrics.setWroteBytes(this.wroteBytes.get());
        metrics.setTimestamp(System.currentTimeMillis());
        metrics.setReadMsgs(this.readMsgs.get());
        metrics.setWroteMsgs(this.wroteMsgs.get());
        return metrics;
    }

    public void incrementReadBytes(long bytes) {
        this.readBytes.addAndGet(bytes);
    }

    public void incrementWroteBytes(long bytes) {
        this.wroteBytes.addAndGet(bytes);
    }

    public void incrementReadMsgs(long msgs) {
        this.readMsgs.addAndGet(msgs);
    }

    public void incrementWroteMsgs(long msgs) {
        this.wroteMsgs.addAndGet(msgs);
    }

    public AtomicInteger getChannels() {
        return this.channels;
    }

    public Integer getPort() {
        return this.port;
    }

    public void setPort(Integer port) {
        this.port = port;
    }
}
